/*
 * @(#)AbstractStartSubWorkflow.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobDataMap;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.Utility;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserRecordDAObject;
import com.dcivision.workflow.bean.MtmWorkflowChildParentProgress;
import com.dcivision.workflow.bean.MtmWorkflowProgressUserRecord;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.bean.WorkflowProgressAttachment;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.bean.WorkflowStepParameterValue;
import com.dcivision.workflow.core.WorkflowProcessor;
import com.dcivision.workflow.core.WorkflowRetrievalManager;
import com.dcivision.workflow.dao.MtmWorkflowChildParentProgressDAObject;
import com.dcivision.workflow.dao.MtmWorkflowProgressUserRecordDAObject;
import com.dcivision.workflow.dao.WorkflowProgressAttachmentDAObject;
import com.dcivision.workflow.dao.WorkflowProgressDAObject;
import com.dcivision.workflow.dao.WorkflowRecordDAObject;
import com.dcivision.workflow.dao.WorkflowStepParameterValueDAObject;

/**
 * This is an abstract class of starting subworkflow.
 *
 * @author TC Tang
 * @company     DCIVision Limited
 * @creation date 01/25/2007
 * @version     $Revision: 1.2 $
 */
public abstract class AbstractStartSubWorkflow extends WorkflowProcessor {
  protected Log log = LogFactory.getLog(this.getClass().getName());
  protected boolean bAllowUploadParentAttachments = false;

  abstract public void execute(JobDataMap jobDataMap, WorkflowProgress currentProgress)
      throws ApplicationException;

  /**
   * get the subWorkflow Record
   * @param sessionCon
   * @param conn
   * @param stepID
   * @return
   * @throws ApplicationException
   */
  protected WorkflowRecord getSubWorkflowRecord(SessionContainer sessionCon,Connection conn,Integer stepID) throws ApplicationException{
    WorkflowStepParameterValueDAObject paraDAO=new WorkflowStepParameterValueDAObject(sessionCon, conn);
    WorkflowRecordDAObject recordDAO = new WorkflowRecordDAObject(sessionCon, conn);
    List tempList=paraDAO.getListByStepID(stepID);
    WorkflowRecord workflowRecord = null;
    if(!Utility.isEmpty(tempList)){
      for (int i = 0; i < tempList.size(); i++) {
        WorkflowStepParameterValue stepParameterValue = (WorkflowStepParameterValue)tempList.get(i);
        if (WorkflowRetrievalManager.PARAMVALUE_SUB_WORKFLOW.equals(stepParameterValue.getParameterType())) {
           workflowRecord=(WorkflowRecord) recordDAO.getEffectiveWorkflowRecordByWorkflowCode(stepParameterValue.getParameterValue());
          if (!Utility.isEmpty(workflowRecord)) {
            log.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>"+workflowRecord.getID());
            return workflowRecord;
          }
        }
      }
    }

    return null;
  }

  /**
   * set the child parent progress ship
   * @param sessionCon
   * @param conn
   * @param currentProgress
   * @param workflowProgress
   * @return
   * @throws ApplicationException
   */
  protected MtmWorkflowChildParentProgress setChildParentProgressShip(SessionContainer sessionCon,Connection conn,WorkflowProgress currentProgress,WorkflowProgress workflowProgress) throws ApplicationException{
    if (this.parentDependent) {
      log.debug("add workflow child parent progress record");
      MtmWorkflowChildParentProgressDAObject subworkflowDAO = new MtmWorkflowChildParentProgressDAObject(sessionCon, conn);
      MtmWorkflowChildParentProgress childWorkflowParentProgress = new MtmWorkflowChildParentProgress();
      childWorkflowParentProgress.setParentWorkflowProgressID(currentProgress.getID());
      childWorkflowParentProgress.setSubworkflowTrackID(workflowProgress.getTrackID());
      childWorkflowParentProgress = (MtmWorkflowChildParentProgress) subworkflowDAO.insertObject(childWorkflowParentProgress);
      log.debug("finish add workflow child parent progress record");
      return childWorkflowParentProgress;
    }
    return null;
  }

  /**
   * if isAllowUploadParentAttachments is true then  bring attachments to subworkflow
   * @param workflowProgress
   * @param parentProgress
   * @param conn
   * @throws Exception
   */
  protected void setSessionContainer(SessionContainer sessionCon,Connection conn,WorkflowProgress currentProgress) throws ApplicationException{
   //set User info-----
    UserRecordDAObject userDAO = new UserRecordDAObject(sessionCon, conn);
    Integer userRecordID = currentProgress.getUpdaterID();
    UserRecord userRecord = (UserRecord) userDAO.getObjectByID(userRecordID);
    sessionCon.setUserRecord(userRecord);
  }

  protected void setSubWorkFlowAttachmentsFromParentProgress(SessionContainer sessionContainer,Connection conn,WorkflowProgress workflowProgress, WorkflowProgress parentProgress) throws Exception {
    InputStream inputStream = null;
    FileOutputStream fos = null;
    int bufferSize = 8192;
    byte[] buffer = new byte[bufferSize];
    int length = -1;
    Integer trackID = parentProgress.getTrackID();

    WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, conn);
    WorkflowProgressAttachmentDAObject attachmentDAO = new WorkflowProgressAttachmentDAObject(sessionContainer, conn);
    MtmWorkflowProgressUserRecordDAObject progressUserRecordDAO = new MtmWorkflowProgressUserRecordDAObject(sessionContainer, conn);
    List progressList = progressDAO.getListByTrackID(trackID);
    List allAttachmentList = new ArrayList();

    List progressUserList = progressUserRecordDAO.getCompletedUserProcessRecordByWorkflowProgressID(workflowProgress.getID());

    Integer progressUserID = null;
    if (!Utility.isEmpty(progressUserList)) {
      MtmWorkflowProgressUserRecord progressUser = (MtmWorkflowProgressUserRecord) progressUserList.get(0);
      progressUserID = new Integer(progressUser.getID().intValue());
    }

    // get all attachments from parent Track
    for (int i = 0; i < progressList.size(); i++) {
      WorkflowProgress progress = (WorkflowProgress) progressList.get(i);
      List subAttachmentList = attachmentDAO.getListByWorkflowProgressID(progress.getID());
      if (!Utility.isEmpty(subAttachmentList)) {
        allAttachmentList.addAll(subAttachmentList);
      }
    }

    for (Iterator iter = allAttachmentList.iterator(); iter.hasNext();) {
      WorkflowProgressAttachment tmpattachment = (WorkflowProgressAttachment) iter.next();
      if (WorkflowProgressAttachment.ATTACHED_SINGLE_FILE.equals(tmpattachment.getAttachmentType())) {
        String filePath = SystemParameterFactory.getSystemParameter(SystemParameterConstant.WORKFLOW_ATTACHMENT_PHYSICAL_PATH);
        String allFileName = filePath + "/" + tmpattachment.getExternalID();
        String convertedName = String.valueOf(System.currentTimeMillis());
        File convertedFile = new File(filePath + "/" + convertedName);
        while (convertedFile.exists()) {
          convertedName = convertedName + String.valueOf(System.currentTimeMillis());
          convertedFile = new File(filePath + "/" + convertedName);
        }
        File newfile = new File(allFileName);
        inputStream = new FileInputStream(newfile);

        WorkflowProgressAttachment attachment = new WorkflowProgressAttachment();
        attachment.setAttachmentName(tmpattachment.getAttachmentName());
        attachment.setExternalID(convertedName);
        attachment.setFlowType(WorkflowProgressAttachment.ATTACHED_SINGLE_FILE);
        attachment.setDataStream(inputStream);
        attachment.setContentSize(new Integer("" + newfile.length()));
        attachment.setAttachmentType(WorkflowProgressAttachment.ATTACHED_SINGLE_FILE);
        attachment.setMtmWorkflowProgressUserRecordID(progressUserID);
        attachmentDAO.insertObject(attachment);

        fos = new FileOutputStream(convertedFile);
        while ((length = inputStream.read(buffer, 0, bufferSize)) != -1) {
          fos.write(buffer, 0, length);
        }
        fos.flush();
        inputStream.close();
        fos.close();
      } else if (WorkflowProgressAttachment.ATTACHED_DMS_VERSION_SYSTEM_ID.equals(tmpattachment.getAttachmentType())) {
        tmpattachment.setMtmWorkflowProgressUserRecordID(progressUserID);
        attachmentDAO.insertObject(tmpattachment);
      }
    }

  }

  public boolean isBAllowUploadParentAttachments() {
    return bAllowUploadParentAttachments;
  }

  public void setBAllowUploadParentAttachments(
      boolean allowUploadParentAttachments) {
    bAllowUploadParentAttachments = allowUploadParentAttachments;
  }
}
